#include"test.h"

istream& operator>>(istream& is,Reading& r)
{
  //input format:(2 12 123.8)
  char ch1;
  if(is>>ch1&&ch1!='(')  //check whether a Reading started with '('
    {
      is.unget();
      is.clear(ios_base::failbit);
      return is;
    }

  char ch2;
  int d;
  int h;
  double t;
  is>>d>>h>>t>>ch2;
  if(!is||ch2!=')') cerr<<"bad reading!";
  r.day=d;
  r.hour=h;
  r.temperature=t;
  return is;
}

istream& operator>>(istream& is,Month& m)
{
  //input format:{month jan...}
  char ch;
  if(is>>ch&&ch!='{')
    {
      is.unget();
      is.clear(ios_base::failbit);
      return is;
    }

  string month_sign,mm;
  is>>month_sign>>mm;
  if(!is||month_sign!="month")
    cerr<<"bad start of month";
  m.month=month_to_int(mm);
  int repetition=0;  //record the repeated time of a date
  int invalid=0;  //record number of invalid datas
  for(Reading r;is>>r;)
    {
      if(is_valid(r))
	{
           if(m.day[r.day].hour[r.hour]!=not_a_reading)
         	repetition++;
           m.day[r.day].hour[r.hour]=r.temperature;
	}
      else
	invalid++;
    }
  if(invalid)
    cerr<<"invalid readings in month";
  if(repetition)
    cerr<<"repeated readings in month";
  end_of_loop(is,'}',"bad end of month");
  return is;
}

istream& operator>>(istream& is,Year& y)
{
  //input format:{year 1989...}
  char ch;
  is>>ch;
  if(ch!='{')
    {
      is.unget();
      is.clear(ios::failbit);
      return is;
    }

  string year_sign;
  int yy;
  is>>year_sign>>yy;
  if(!is||year_sign!="year")
    cerr<<"bad start of year!";
  y.year=yy;

  while(true)
    {
      Month m;
      if(!(is>>m)) break;
      y.month[m.month]=m;
    }

  end_of_loop(is,'}',"bad end of year");
  return is;
}

int month_to_int(const string& month)
{
  for(int i=0;i<12;i++)
    if(month_table[i]==month)
      return i;
  return -1;
}

bool is_valid(const Reading& r)
{
  if(r.day<1||r.day>31)
    return false;
  if(r.hour<1||r.hour>24)
    return false;
  if(r.temperature>degree_max||r.temperature<degree_min)
    return false;
  return true;
}

void end_of_loop(istream& ist,const char term,const string& message)
{
  if(ist.fail())
    {
      ist.clear();
      char ch;
      if(ist>>ch&&ch==term)
	return;
      cerr<<message<<endl;
    }
}
